package com.wyh.lotterysystem.service.activitystatus.impl;

import com.wyh.lotterysystem.common.errorcode.ServiceErrorCodeConstants;
import com.wyh.lotterysystem.common.exception.ServiceException;
import com.wyh.lotterysystem.common.utils.JacksonUtil;
import com.wyh.lotterysystem.common.utils.RedisUtil;
import com.wyh.lotterysystem.dao.dataobject.ActivityDo;
import com.wyh.lotterysystem.dao.dataobject.ActivityPrizeDo;
import com.wyh.lotterysystem.dao.dataobject.ActivityUserDo;
import com.wyh.lotterysystem.dao.dataobject.PrizeDo;
import com.wyh.lotterysystem.dao.mapper.ActivityMapper;
import com.wyh.lotterysystem.dao.mapper.ActivityPrizeMapper;
import com.wyh.lotterysystem.dao.mapper.ActivityUserMapper;
import com.wyh.lotterysystem.dao.mapper.PrizeMapper;
import com.wyh.lotterysystem.service.ActivityService;
import com.wyh.lotterysystem.service.activitystatus.ActivityStatusManager;
import com.wyh.lotterysystem.service.activitystatus.operator.AbstractActivityOperator;
import com.wyh.lotterysystem.service.dto.ActivityDetailDTO;
import com.wyh.lotterysystem.service.dto.ConvertActivityStatusDTO;
import com.wyh.lotterysystem.service.enums.ActivityPrizeStatusEnum;
import com.wyh.lotterysystem.service.enums.ActivityPrizeTiersEnum;
import com.wyh.lotterysystem.service.enums.ActivityStatusEnum;
import com.wyh.lotterysystem.service.enums.ActivityUserStatusEnum;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


@Component
@Slf4j
public class ActivityStatusManagerImpl implements ActivityStatusManager {

    @Autowired
    private final Map<String, AbstractActivityOperator> operatorMap = new HashMap<>();

    @Autowired
    RedisUtil redisUtil;

    private static final String ACTIVITY_PREFIX = "activity_id";

    private static final Long ACTIVITY_TIMEOUT = 60*60*24*3L;

    @Autowired
    ActivityMapper activityMapper;

    @Autowired
    ActivityUserMapper activityUserMapper;

    @Autowired
    ActivityPrizeMapper activityPrizeMapper;

    @Autowired
    PrizeMapper prizeMapper;

    @Resource(name = "activityServiceImpl")
    ActivityService activityService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        //采用责任链模式和策略模式
        Integer activityId = convertActivityStatusDTO.getActivityId();

        boolean update = false;
        //先扭转奖品和人员状态,再扭转活动状态
        Map<String,AbstractActivityOperator> map = new HashMap<>(operatorMap);
        update = processConvertStatus(convertActivityStatusDTO,map,1);

        if (update){
            processConvertStatus(convertActivityStatusDTO,map,2);
        }else {
            update = processConvertStatus(convertActivityStatusDTO,map,2);
        }

        //如果扭转成功的话就更新缓存
        if (update){
            // 整合活动详细信息，存放redis
            activityService.cacheActivityByActivityId(activityId);
        }

    }

//    private void cacheActivity(ActivityDetailDTO detailDTO) {
//        if (detailDTO == null || detailDTO.getActivityId() == null){
//            log.warn("要缓存的数据为空");
//            return;
//        }
//
//        try {
//            redisUtil.setRedisAndTime(ACTIVITY_PREFIX+detailDTO.getActivityId(),
//                    JacksonUtil.writeValueAsString(detailDTO),ACTIVITY_TIMEOUT);
//        }catch (Exception e) {
//            log.warn("活动信息缓存失败, detailDTO：{}",JacksonUtil.writeValueAsString(detailDTO));
//        }
//    }
//
//    private ActivityDetailDTO convertToActivityDetailDTO(List<PrizeDo> prizeDos,
//                                                         ActivityDo activityDo,
//                                                         List<ActivityUserDo> activityUserDos,
//                                                         List<ActivityPrizeDo> activityPrizeDos) {
//        ActivityDetailDTO detailDTO = new ActivityDetailDTO();
//
//        //构造返回值
//
//        //1.活动信息
//        detailDTO.setActivityName(activityDo.getActivityName());
//        detailDTO.setDesc(activityDo.getDescription());
//        detailDTO.setStatus(ActivityStatusEnum.forName(activityDo.getStatus()));
//        detailDTO.setActivityId(activityDo.getId());
//
//        //2.奖品信息
//        List<ActivityDetailDTO.PrizeDTO> prizeDTOS = activityPrizeDos.stream().map(activityPrizeDo -> {
//            ActivityDetailDTO.PrizeDTO prizeDTO = new ActivityDetailDTO.PrizeDTO();
//
//            prizeDTO.setPrizeId(activityPrizeDo.getPrizeId());
//            Optional<PrizeDo> first = prizeDos.stream().filter(prizeDo -> prizeDo.getId()
//                    .equals(activityPrizeDo.getPrizeId())).findFirst();
//            first.ifPresent(prizeDo -> {
//                prizeDTO.setName(prizeDo.getName());
//                prizeDTO.setPrice(prizeDo.getPrice());
//                prizeDTO.setDescription(prizeDo.getDescription());
//                prizeDTO.setImageUrl(prizeDo.getImageUrl());
//            });
//            prizeDTO.setTiers(ActivityPrizeTiersEnum.forName(activityPrizeDo.getPrizeTiers()));
//            prizeDTO.setPrizeAmount(activityPrizeDo.getPrizeAmount());
//            prizeDTO.setStatus(ActivityPrizeStatusEnum.forName(activityPrizeDo.getStatus()));
//            return prizeDTO;
//        }).toList();
//        detailDTO.setPrizeDTOList(prizeDTOS);
//
//        //用户信息
//        List<ActivityDetailDTO.UserDTO> userDTOS = activityUserDos.stream().map(activityUserDo -> {
//            ActivityDetailDTO.UserDTO userDTO = new ActivityDetailDTO.UserDTO();
//            userDTO.setUserName(activityUserDo.getUserName());
//            userDTO.setUserId(activityUserDo.getUserId());
//            userDTO.setStatus(ActivityUserStatusEnum.forName(activityUserDo.getStatus()));
//            return userDTO;
//        }).toList();
//        detailDTO.setUserDTOList(userDTOS);
//
//        return detailDTO;
//    }

    /**
     * 扭转状态
     * @param convertActivityStatusDTO
     * @param map
     * @param i
     * @return
     */
    private boolean processConvertStatus(ConvertActivityStatusDTO convertActivityStatusDTO, Map<String, AbstractActivityOperator> map, int i) {
        boolean update = false;
    
        Iterator<Map.Entry<String,AbstractActivityOperator>> iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            AbstractActivityOperator activityOperator = iterator.next().getValue();

            //检查operator是否需要扭转状态
            if (activityOperator.sequence() != i
                    || !activityOperator.needConvert(convertActivityStatusDTO)){
                continue;
            }

            //转换
            if (!activityOperator.convertStatus(convertActivityStatusDTO)){
                log.error("{}状态扭转失败",activityOperator.getClass().getName());
                throw new ServiceException(ServiceErrorCodeConstants.ACTIVITY_STATUS_CONVERT_ERROR);
            }

//            iterator.remove();
            update = true;
        }

        return update;
    }

    @Override
    public void rollbackHandlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        for (AbstractActivityOperator activityOperator : operatorMap.values()){
            activityOperator.convertStatus(convertActivityStatusDTO);
        }

        activityService.cacheActivityByActivityId(convertActivityStatusDTO.getActivityId());
    }
}
